README
Haskell Implementation of the JSON-API specification
Attribution
This codebase is a fork of the original json-api lib authored by Todd Mohney.
The specification
Find the specification here
Example usage
Let's start with a simple User resource record:
data UserResource = UserResource
{ resourceId :: Text
, emailAddress :: Text
, firstName :: Text
, middleName :: Maybe Text
, lastName :: Text
} deriving (Eq, Show)
$(deriveJSON defaultOptions ''UserResource)
instance ResourcefulEntity UserResource where
resourceIdentifier = resourceId
resourceType _ = "users"
resourceLinks = Just . JSONApi.showLink
resourceMetaData _ = Nothing
resourceRelationships _ = Nothing
From this, we can use the json-api
package to produce a payload conformant
to the JSON-API specification like so:
-- Import the JSON API
import qualified Network.JSONApi as JSONApi
-- Builds the Document which will be serialized as our
-- web server's response payload
let userResource = UserResource {
resourceId = "8b384d842a8b33fdcaf6207ad45b62c9"
, emailAddress = "[email protected]"
, firstName = "John"
, middleName = "Adrian"
, lastName = "Doe"
}
JSONApi.mkDocument userResource Nothing Nothing
When delivered as a response from a web server, for example, we get a payload that looks like this:
{
"data": {
"attributes": {
"resourceId": "8b384d842a8b33fdcaf6207ad45b62c9",
"middleName": "Adrian",
"lastName": "Doe",
"emailAddress": "[email protected]",
"firstName": "John"
},
"relationships": null,
"id": "8b384d842a8b33fdcaf6207ad45b62c9",
"meta": null,
"type": "users",
"links": {
"self": "/users/8b384d842a8b33fdcaf6207ad45b62c9"
}
},
"meta": null,
"included": [],
"links": null
}
Now suppose you want to send back a collection of resources (e.g: User resources).
-- Import the JSON API
import qualified Network.JSONApi as JSONApi
-- Builds the Document which will be serialized as our
-- web server's response payload
let userResource1 = UserResource {
resourceId = "8b384d842a8b33fdcaf6207ad45b62c9"
, emailAddress = "[email protected]"
, firstName = "John"
, middleName = Nothing
, lastName = "Doe"
}
let userResource2 = UserResource {
resourceId = "8b384d842a8b33fdcaf6207ad45b62c9"
, emailAddress = "[email protected]"
, firstName = "Jane"
, middleName = Nothing
, lastName = "Doe"
}
JSONApi.mkDocuments [userResource1, userResource2] Nothing Nothing
When delivered as a response from a web server, for example, we get a payload that looks like this:
{
"data": [{
"attributes": {
"resourceId": "8b384d842a8b33fdcaf6207ad45b62c9",
"middleName": "Adrian",
"lastName": "Doe",
"emailAddress": "[email protected]",
"firstName": "John"
},
"relationships": null,
"id": "8b384d842a8b33fdcaf6207ad45b62c9",
"meta": null,
"type": "users",
"links": {
"self": "/users/8b384d842a8b33fdcaf6207ad45b62c9"
}},{
"attributes": {
"resourceId": "8b384d842a8b33fdcaf6207ad45b62c8",
"lastName": "Doe",
"emailAddress": "[email protected]",
"firstName": "Jane"
},
"relationships": null,
"id": "8b384d842a8b33fdcaf6207ad45b62c8",
"meta": null,
"type": "users",
"links": {
"self": "/users/8b384d842a8b33fdcaf6207ad45b62c8"
}
}]
},
"meta": null,
"included": [],
"links": null
}
Example Project
There is an example project illustrating how the library can be used in the context of a web application.
Hackage
Module documentation can be found on Hackage